import threading

import obspython as obs
import blivedm
import asyncio

roomID = 0
source_name = ""
main_loop: asyncio.AbstractEventLoop = None
msgData = ["","","","",""] #默认为5行
nextPos = 0

def setSourceString(sourceName,data):
    source = obs.obs_get_source_by_name(source_name)
    if source is not None:
        settings = obs.obs_data_create()
        obs.obs_data_set_string(settings, "text", data)
        obs.obs_source_update(source, settings)
        obs.obs_data_release(settings)

def updateMsg(data):
    global nextPos
    msgData[nextPos] = data
    nextPos += 1
    nextPos %= len(msgData)
    output = ""
    for item in msgData:
        output += item + "\n"
    setSourceString(source_name,output)

class MyBLiveClient(blivedm.BLiveClient):
    # 演示如何自定义handler
    _COMMAND_HANDLERS = blivedm.BLiveClient._COMMAND_HANDLERS.copy()

    async def __on_vip_enter(self, command):
        updateMsg(command)

    _COMMAND_HANDLERS['WELCOME'] = __on_vip_enter  # 老爷入场

    async def _on_receive_popularity(self, popularity: int):
        updateMsg(f'当前人气值：{popularity}')

    async def _on_receive_danmaku(self, danmaku: blivedm.DanmakuMessage):
        updateMsg(f'{danmaku.uname}：{danmaku.msg}')

    async def _on_receive_gift(self, gift: blivedm.GiftMessage):
        updateMsg(f'{gift.uname} 赠送{gift.gift_name}x{gift.num} （{gift.coin_type}币x{gift.total_coin}）')

    async def _on_buy_guard(self, message: blivedm.GuardBuyMessage):
        updateMsg(f'{message.username} 购买{message.gift_name}')

    async def _on_super_chat(self, message: blivedm.SuperChatMessage):
        updateMsg(f'醒目留言 ¥{message.price} {message.uname}：{message.message}')


async def main():
    global roomID
    client = MyBLiveClient(roomID, ssl=True)
    future = client.start()
    try:
        await future
    finally:
        await client.close()


def thread_loop(loop: asyncio.AbstractEventLoop):
    asyncio.set_event_loop(loop)
    loop.run_forever()


def start_pressed(props, prop):
    global main_loop
    if roomID != 0:
        if main_loop != None:
            main_loop.stop()
            del main_loop
            main_loop = None
        main_loop = asyncio.new_event_loop()
        t = threading.Thread(target=thread_loop, args=(main_loop,), daemon=True)
        t.start()
        asyncio.run_coroutine_threadsafe(main(), main_loop)


def end_pressed(props, prop):
    global main_loop
    if main_loop != None:
        main_loop.stop()
        del main_loop
        main_loop = None


# ------------------------------------------------------------

def script_description():
    return "从Bilibili指定房间号获取弹幕并且显示到一个Text组件上"


def script_update(settings):
    global roomID
    global source_name
    roomID = obs.obs_data_get_string(settings, "roomID")
    source_name = obs.obs_data_get_string(settings, "source")


def script_defaults(settings):
    obs.obs_data_set_default_string(settings, "roomID", "6")


def script_properties():
    props = obs.obs_properties_create()

    obs.obs_properties_add_text(props, "roomID", "Bilibili直播房间号", obs.OBS_TEXT_DEFAULT)

    p = obs.obs_properties_add_list(props, "source", "文本组件", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
    sources = obs.obs_enum_sources()
    if sources is not None:
        for source in sources:
            source_id = obs.obs_source_get_unversioned_id(source)
            if source_id == "text_gdiplus" or source_id == "text_ft2_source":
                name = obs.obs_source_get_name(source)
                obs.obs_property_list_add_string(p, name, name)

        obs.source_list_release(sources)

    obs.obs_properties_add_button(props, "button", "开始", start_pressed)
    obs.obs_properties_add_button(props, "button2", "结束", end_pressed)
    return props
